<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
              原型对象  prototype
               js 规定  我们每创建一个函数就会有一个prototype属性，指向一个对象
               指向的这个对象就是我们所谓的原型对象
                   -访问原型对象的方式：函数名.prototype
                   -如果函数作为普通函数调用prototype属性时基本没有作用，但是对于构造函数来说，生成实例时，
                   该属性会自动成为实例对象的原型对象
      
      
                   --原型对象相当于一个公共区域，所有同一类（同一个构造函数）实例都能够访问这个原型对象的内容（原型上
                   的内容都能够被实例所共享），我们可以把对象中共有的内容，统一设置到原型对象中。
      
                   --当我们访问对象的属性和方法时，首先会在对象自身中寻找，如果有则直接使用，如果对象自身没有，
                   则去原型对象中寻找，如果有则直接使用
      
      
                   --将对象中共有的属性和方法定义在原形中的好处
                           --  不会污染全局作用域
                           --  方法和属性不会被覆盖
                           --  添加到原型的属性和方法能够被实例之间所共享
          */
      /*
            constructor 
                原型对象上的属性
                每一个原型对象都有一个 constructor 属性，默认指向原型对象所在的构造函数
                由于 constructor 属性定义在原型对象上，即意味着实例对象能够继承该属性（实例对象能够使用该属性）
                constructor 属性的作用： 可以得知某个实例对象的构造函数是谁！


        */

      /*
            new 运算符（执行代码时做的四件事）
                创建一个空对象
                修改构造函数的this指向
                执行构造函数的代码
                返回这个新对象
                

        */

      function Po(a, b, c) {
        this.a = a
        this.b = b
        this.c = c
      }
      Po.prototype.q = function () {
        console.log("睡觉")
      }
      Po.prototype.w = "河南"
      const obj = new Po("999", 10, "男")
      const obj1 = new Po("666", 10, "女")
      console.log(obj1, obj) //两个实例
      obj.q()
      obj1.q()
      console.log(obj.q === obj1.q) //同一个方法
      console.log(obj.w, obj1.w) // 定义在原型上的属性和方法能被实例之间共享
      console.log(obj1.constructon)

      /*
            构造函数的实例对象都会有一个隐含的属性（这个属性指向该构造函数的原型对象），该隐含参数为__proto__,我们
            可以通过该隐含属性来访问该构造函数的原型对象
        
            原型链就是通过这个属性来构建的在谷歌浏览器中__proto__ 这个属性[[prototype]]表示
        */

      //  __proto__ 对象和函数都有的隐藏属性  指向这个对象或函数的原型对象

      function Name(a, b, c) {
        this.a = a
        this.b = b
        this.c = c
      }
      const obj2 = new Name("小美女", 18, 140)
      console.log(obj2.__proto__ === Name.prototype)
      console.log(Name.__proto__ === Function.prototype)
      //任何函数的构造函数都是Function（是一个内置对象）

      // 原型链就是通过__proto__往上查找，从而形成的链式结构
    </script>
  </body>
</html>
